#include "RingQueue.hpp"
#include "Thread.hpp"
#include "Task.hpp"
#include <string>
#include <vector>
#include <unistd.h>
#include <ctime>

using namespace ThreadModule;
using namespace std;
using ringqueue_t=RingQueue<Task>;

void Consumer(ringqueue_t &rq,string name)
{
    while(true)
    {
        sleep(2);
        Task t;
        rq.Popqueue(&t);
        std::cout << "Consumer handler task: " << "[" << name << "]" << std::endl;
        t();
    }
}

void Productor(ringqueue_t &rq,string name)
{
    while(true)
    {
        Task task=Download;
        rq.Enqueue(task);
        std::cout << "Productor : " << "[" << name << "]" << std::endl;
    }
}


void Initcomm(vector<Thread<ringqueue_t>> *threads,int num,ringqueue_t &rq,func_t<ringqueue_t> func,const string &who)
{
    for(int i=0;i<num;i++)
    {
        string name="thread-"+to_string(i+1)+"-"+who;
        threads->emplace_back(func,rq,name);
    }
}

void InitProductor(vector<Thread<ringqueue_t>> *threads,int num,ringqueue_t &rq)
{
    Initcomm(threads,num,rq,Productor,"productor");//"productor"是const类型，所以接收他的参数也必须是const类型
}

void InitConsumer(vector<Thread<ringqueue_t>> *threads,int num,ringqueue_t &rq)
{
    Initcomm(threads,num,rq,Consumer,"consumer");
}

void StartAll(vector<Thread<ringqueue_t>> &threads)
{
    for(auto &thread:threads)
    {
        cout<<"start:"<<thread.name()<<endl;
        thread.Start();
    }
}

void WaitAllThread(vector<Thread<ringqueue_t>> &threads)
{
    for (auto &thread : threads)
    {
        thread.Join();
    }
}

int main()
{
    ringqueue_t *rq=new RingQueue<Task>(10);//T=Task
    vector<Thread<ringqueue_t>> threads;//T=ringqueue_t

    InitProductor(&threads,3,*rq);
    InitConsumer(&threads,4,*rq);

    StartAll(threads);

    WaitAllThread(threads);
}